function curry(fn) {
    let args = [];
    console.log(fn.length);
    const inner = function () {
        args = args.concat(...arguments);
        console.log(args);
        if (args.length == fn.length) {
            return fn(...args);
        } else {
            return inner;
        }
    }
    return inner;
}

const sum = (a, b, c, d) => a + b + c + d;
const currySum = curry(sum);
console.log(currySum(1)(2)(3)(4));



function add() {
    console.log(arguments);
    // 这一句是为了让args 为数组，可以用下面的push方法
    let args = Array.prototype.splice.call(arguments);
    // console.log(args);
    let fn = function () {
        args.push(...arguments)
        return fn;
    }
    // 默认如果直接返回fn 其实是进行了强制转换。返回fn 是一个字符串，
    // 原因是调用了函数默认的tostring()方法
    // 这里我们就用这个特性，执行fn.toString，并把toString改写成 遍历最终函数参数相加
    fn.toString = function () {
        return args.reduce((a, b) => {
            return a + b;
        });
    }
    return fn;
}

// console.log(typeof add(1));
// console.log(add(1, 2));

// add(1)(); 			// 1
// add(1)(2)();  	// 3
// add(1)(2)(3)();// 6
// add(1)(2, 3)(); // 6
// add(1, 2)(3)(); // 6
add(1, 2, 3); // 6


// 组合多个函数，从右到左，比如：compose(f, g, h) 最终得到这个结果(...args) => f(g(h(...args))).
const compose = function (...fns) {
    return function (...args) {
        let lastFun = fns.pop();
        return fns.reduceRight((prev, cur) => {
            return cur(prev)
        }, lastFun(...args));
    }
}


function compose(...funs) {
    if (funs.length === 0) {
        return arg => arg;
    }
    if (funs.length === 1) {
        return funs[0];
    }
    return funs.reduce((a, b) => (...arg) => a(b(...arg)));
}